package com.wit.witmg.util;

import java.io.IOException;

public class ModbusReader {
    private ModbusTCPClient client;
    private final int unitId; // 设备地址

    public ModbusReader(String host, int port, int unitId) {
        this.client = new ModbusTCPClient(host, port);
        this.unitId = unitId;
    }

    /**
     * 读取输入继电器 (1区) - 功能码 0x02
     */
    public boolean[] readInputRelays(int startAddress, int quantity) throws IOException {
        byte[] request = client.createReadRequest(unitId, 0x02, startAddress, quantity);
        byte[] response = client.sendRequest(request);

        if (response[0] != 0x02) {
            throw new IOException("响应功能码错误");
        }

        int byteCount = response[1] & 0xFF;
        boolean[] results = new boolean[quantity];

        for (int i = 0; i < quantity; i++) {
            int byteIndex = 2 + i / 8;
            int bitIndex = i % 8;
            results[i] = ((response[byteIndex] >> bitIndex) & 0x01) == 0x01;
        }

        return results;
    }

    /**
     * 读取输出继电器 (0区) - 功能码 0x01
     */
    public boolean[] readOutputRelays(int startAddress, int quantity) throws IOException {
        byte[] request = client.createReadRequest(unitId, 0x01, startAddress, quantity);
        byte[] response = client.sendRequest(request);

        if (response[0] != 0x01) {
            throw new IOException("响应功能码错误");
        }

        int byteCount = response[1] & 0xFF;
        boolean[] results = new boolean[quantity];

        for (int i = 0; i < quantity; i++) {
            int byteIndex = 2 + i / 8;
            int bitIndex = i % 8;
            results[i] = ((response[byteIndex] >> bitIndex) & 0x01) == 0x01;
        }

        return results;
    }

    /**
     * 读取输入寄存器 (3区) - 功能码 0x04
     */
    public int[] readInputRegisters(int startAddress, int quantity) throws IOException {
        byte[] request = client.createReadRequest(unitId, 0x04, startAddress, quantity);
        byte[] response = client.sendRequest(request);

        if (response[0] != 0x04) {
            throw new IOException("响应功能码错误");
        }

        int byteCount = response[1] & 0xFF;
        int[] results = new int[quantity];

        for (int i = 0; i < quantity; i++) {
            int offset = 2 + i * 2;
            results[i] = ((response[offset] & 0xFF) << 8) | (response[offset + 1] & 0xFF);
        }

        return results;
    }

    /**
     * 读取输出寄存器 (4区) - 功能码 0x03
     */
    public int[] readHoldingRegisters(int startAddress, int quantity) throws IOException {
        byte[] request = client.createReadRequest(unitId, 0x03, startAddress, quantity);
        byte[] response = client.sendRequest(request);

        if (response[0] != 0x03) {
            throw new IOException("响应功能码错误");
        }

        int byteCount = response[1] & 0xFF;
        int[] results = new int[quantity];

        for (int i = 0; i < quantity; i++) {
            int offset = 2 + i * 2;
            results[i] = ((response[offset] & 0xFF) << 8) | (response[offset + 1] & 0xFF);
        }

        return results;
    }

    public boolean connect() {
        return client.connect();
    }

    public void disconnect() {
        client.disconnect();
    }
}
